package com.hzjh.base.web.process

import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import android.util.ArrayMap
import android.util.Log
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.ProcessUtils
import com.blankj.utilcode.util.Utils
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.hzjh.base.web.IBridgeInvokeMainProcess
import com.hzjh.base.web.IBridgeInvokeWebProcess
import com.hzjh.base.web.util.WebLog

class BridgeInvokeDispatcher : ServiceConnection {
    companion object {
        private const val TAG = "GuangWebView"

        @Volatile
        private var sInstance: BridgeInvokeDispatcher? = null

        fun getInstance(): BridgeInvokeDispatcher {
            if (sInstance == null) {
                synchronized(this) {
                    if (sInstance == null) {
                        sInstance = BridgeInvokeDispatcher()
                    }
                }
            }
            return sInstance!!
        }
    }
    // 用于切线程
    private val mHandle = Handler(Looper.getMainLooper())
    private var iBridgeInvokeMainProcess: IBridgeInvokeMainProcess? = null
    private val mCommandMap: ArrayMap<String, IBridgeCommand> by lazy { BridgeUtil.autoRegist() }
    private var receiveMsgListener=object :IBridgeInvokeWebProcess.Stub() {
        override fun handleBridgeCallback(callback: String?, params: String?) {
            //接收到服务器的消息
            WebLog.d(TAG,  "当前进程：${ProcessUtils.getCurrentProcessName()}")
            WebLog.d(TAG, "receiveMsgListener---接收到主进程的消息 $callback $params")
            // map 中存在命令 则执行
            if (mCommandMap.contains(callback)) {
                mHandle.post { // 切换到主线程 获取命令 执行
                    mCommandMap[callback]!!.exec(parseParams(params), null)
                }
            } else {
                Log.e(TAG,"command[${callback}] is not register!")
            }
        }

        override fun getValueForKey(key: String?): String {
            WebLog.d(TAG,  "当前进程：${ProcessUtils.getCurrentProcessName()}")
            WebLog.d(TAG, "receiveMsgListener---接收到主进程的消息 $key ")
            return ValueForKeyBridge.exec(key)
        }
    }
    fun bindService() {
        if (iBridgeInvokeMainProcess == null) {
            WebLog.d(TAG, "bindService()")
            val i = Intent(Utils.getApp(), BridgeCommandService::class.java)
            Utils.getApp().bindService(i, this, Context.BIND_AUTO_CREATE)
        }
    }

    fun unbindService() {
        WebLog.d(TAG, "unbindService()")
        iBridgeInvokeMainProcess = null
        Utils.getApp().unbindService(this)
    }

    override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
        iBridgeInvokeMainProcess = IBridgeInvokeMainProcess.Stub.asInterface(service)
        try {
            iBridgeInvokeMainProcess?.registerReceiveListener(receiveMsgListener)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    override fun onServiceDisconnected(name: ComponentName?) {
        try {
            iBridgeInvokeMainProcess?.unregisterReceiveListener(receiveMsgListener)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        iBridgeInvokeMainProcess = null
    }

    //web进程向主进程发送消息
    fun sendCommand(message: BridgeMessage?) {
        WebLog.d(TAG, "web进程->主进程 sendCommand() message: $message")
        if (checkMessage(message)) {
            // 校验命令通过后 执行命令
            excuteCommand(message)
        }
    }
    //web进程向主进程发送消息
    fun  sendValueForKey(key: String?): String {
        WebLog.d(TAG, "web进程->主进程 getValueForKey() key：${key}")
        return iBridgeInvokeMainProcess?.getValueForKey(key)?:""
    }

    // 校验命令、参数 合法性
    private fun checkMessage(message: BridgeMessage?): Boolean {
        if (message == null) {
            Log.e(TAG, "send() jsBridgeParam is null")
            return false
        }
        if (message.name.isNullOrEmpty()) {
            Log.e(TAG, "send() jsBridgeParam.name is null")
            return false
        }
        return true
    }

    //执行命令
    private fun excuteCommand(message: BridgeMessage?) {
        if (iBridgeInvokeMainProcess != null){
            iBridgeInvokeMainProcess?.handleBridgeInvoke(message?.name, Gson().toJson(message?.data), null)
        }else{
            Log.e(TAG, "excuteCommand() iBridgeInvokeMainProcess is null")
        }
    }

    private fun parseParams(params: String?): JsonObject? {
        if (params.isNullOrEmpty()) {
            return null
        }
        return GsonUtils.fromJson(params, JsonObject::class.java)
    }

}